#include "ThreadContainer.h"
#include <iostream>

using namespace std;

FILE* g_src_file = NULL;
FILE* g_dst_video_file = NULL;

unsigned char* g_src_buffer = NULL;
int            g_src_buffer_size = 4 * 1024 * 1024;

unsigned char* g_dst_buffer = NULL;
int            g_dst_buffer_size = 4 * 1024 * 1024;

thread_container::thread_container()
{
    m_a = 5;
    m_b = 10;
}

thread_container::~thread_container()
{
    //m_dthread_producer.join();
    //m_dthread_customer.join();
}

void thread_container::producer_func(int a)
{
    int read_data_length = 0;
    int data_size = 20 *1034 ;
    //cout << a << endl;
    if (NULL != g_src_file)
    {
        read_data_length = ::fread((void*)g_src_buffer, 1, data_size, g_src_file);

        if (0 < read_data_length && !feof(g_src_file))
        {
            printf("in producer_func ring_buffer size:%d\n", m_ring_buffer.size());
            while (1)
            {
                
                if (data_size < m_ring_buffer.left_space())
                {
                    m_ring_buffer.push(g_src_buffer, read_data_length);
                    printf("producer thread. get stream, stream length = %d\n", read_data_length);
                    break;
                }
                else
                {
                    printf("producer thread. don't hava enough space, left space:%d\n", m_ring_buffer.left_space());
                }
            }
        }
        
        memset(g_src_buffer, 0x00, g_src_buffer_size);
    }
}

void thread_container::customer_func(int a)
{
    int write_data_length = 0;
    int data_size = 30 * 1024;

    if (NULL != g_dst_video_file)
    {
        if (data_size < m_ring_buffer.size())
        {
            printf("in customer_func ring_buffer size:%d\n", m_ring_buffer.size());
            int pop_ret = m_ring_buffer.pop(g_dst_buffer, data_size);

            if (0 < pop_ret)
            {
                write_data_length = ::fwrite((void*)g_dst_buffer, 1, data_size, g_dst_video_file);
                printf("customer thread. get stream, stream length = %d, data:%s\n", write_data_length, g_dst_buffer);
            }
        }

        memset(g_dst_buffer, 0x00, g_dst_buffer_size);
    }
}

int thread_container::open_files()
{
    char* src_file_name = "d://20200305145917.ts";
    char* dst_video_file_name = "d://20200305145917_back.ts";

    int ret = ::fopen_s(&g_src_file, src_file_name, "rb+");
    if (NULL == g_src_file)
    {
        return -1;
    }

    ret = ::fopen_s(&g_dst_video_file, dst_video_file_name, "wb+");
    if (NULL == g_src_file)
    {
        return -1;
    }

    g_src_buffer = new unsigned char[g_src_buffer_size];
    memset(g_src_buffer, 0x00, g_src_buffer_size);

    g_dst_buffer = new unsigned char[g_dst_buffer_size];
    memset(g_dst_buffer, 0x00, g_dst_buffer_size);
}

void thread_container::close_files()
{
    if (NULL != g_src_file)
    {
        ::fclose(g_src_file);
    }

    if (NULL != g_dst_video_file)
    {
        ::fclose(g_dst_video_file);
    }
}

int thread_container::start()
{
    m_dthread_producer.set_work(producer_thread_func, this);
    m_dthread_producer.start();
    //m_dthread_producer.join();

    m_dthread_customer.set_work(consumer_thread_func, this);
    m_dthread_customer.start();
   // m_dthread_customer.join();

    return 0;
}

int thread_container::stop()
{
    m_dthread_producer.stop();
    m_dthread_customer.stop();
    return 0;
}

void* thread_container::producer_thread_func(void* param)
{
    thread_container* container = (thread_container*)param;
    if (NULL != container)
    {
        container->producer_func(container->m_a);
    }

    return NULL;
}

void* thread_container::consumer_thread_func(void* param)
{
    thread_container* container = (thread_container*)param;
    if (NULL != container)
    {
        container->customer_func(container->m_b);
    }

    return NULL;
}